package org.finalministry.database;

import geodb.GeoDB;

import java.sql.Connection;
import java.sql.SQLException;

import org.h2.tools.Server;
import org.springframework.jdbc.datasource.DriverManagerDataSource;

/**
 * The embedded H2 Database to which we connect.
 * <p>
 * 1) Initialize the database with a GeoDB spatially enabled<br>
 * 2) Connect via DaoFactory
 * 
 * @author admin
 * 
 */
public class FinalministryDatabase extends Thread implements IH2Database {

	private Server server;
	private DriverManagerDataSource dataSource;
	private boolean runs = false;

	private String databaseName;
	private String username;
	private String password;
	private int port;

	/**
	 * Just for test purposes
	 * 
	 * @param args
	 */
	public static void main(String[] args) {
		FinalministryDatabase database;
		try {
			database = new FinalministryDatabase("finalministryTest", "sa", "sa", 7786);
			database.start();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}

	}

	/**
	 * Maybe you need to execute a CREATE ALIAS of all functions from
	 * geodb.GeoDB initially for enabling spatial methods.
	 * 
	 * @throws ClassNotFoundException
	 */
	public FinalministryDatabase(String databaseName, String username, String password, int port) throws ClassNotFoundException {
		this.databaseName = databaseName;
		this.username = username;
		this.password = password;
		this.port = port;
	}

	private void startServer() throws Exception {

		if (runs) {
			System.err.println("Server already run. Stop it if you want to restart.");
			return;
		}

		try {

			dataSource = new DriverManagerDataSource();
			dataSource.setDriverClassName("org.h2.Driver");
			dataSource.setUrl("jdbc:h2:tcp://localhost:" + port + "/~/" + databaseName + ";ACCESS_MODE_DATA=rw");
			dataSource.setUsername(username);
			dataSource.setPassword(password);

			server = Server.createWebServer(new String[] { "-web", "-webPort", "7786" }).start();
			System.out.println(server.getURL());

			System.out.println("Get a connection for enabling the H2 Database with GeoDB spatial methods ...");
			Connection connection = dataSource.getConnection();
			GeoDB.InitGeoDB(connection);
			System.out.println("... GeoDB Init successful!");
			Server.startWebServer(connection);
			System.out.println("WebServer for H2 startet!");

			runs = true;

			System.out.println("... now Database is running ...");

		} catch (SQLException e) {

			e.printStackTrace();
		}

	}

	@Override
	public void stopServer() {
		if (runs && server != null) {
			System.out.println("Let's stop the server properly.");
			runs = false;
			server.stop();
		}
	}

	@Override
	public boolean isRunning() {

		return runs;
	}

	@Override
	public void run() {

		System.out.print("Start Thread for Database ... ");

		try {
			startServer();

		} catch (Exception e) {
			System.out.println("Error after starting server ...");
			e.printStackTrace();
		}

		boolean runOnes = true;

		while (runs) {

			try {
				Thread.sleep(250);

			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}

		System.out.println("Finalministry Database Thread running out ... Good bye!");

	}
}
